﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace Framework.AssetsManager
{
    public delegate void OnLoadFinish(bool _success);

    public class LoadModule
    {
        private List<LoadTask> m_webTasks = new List<LoadTask>();

        private bool m_isLoading = false;

        private const int LOAD_COUNT_ONE_FRAME = 25;


        private LoadTask m_curTask = null;
        private uint m_curIndex = 0;

        public int webTasksCount
        {
            get { return m_webTasks.Count; }
        }


        public bool isLoading
        {
            get { return m_isLoading; }
        }


        public float progress
        {
            get
            {
                if (m_isLoading)
                {
                    if (m_curTask == null)
                        return 1.0f;
                    return (m_curIndex + m_curTask.progress) / m_webTasks.Count;
                }
                else
                    return 1.0f;
            }
        }
        
        private static LoadModule _instance;

        public static LoadModule Instance
        {
            get
            {
                if(_instance == null)
                {
                    _instance = new LoadModule();
                }
                return _instance;
            }
        }

        private LoadModule()
        {

        }

        public void AddTask(AssetData _data)
        {
            if (_data != null)
                AddTask(_data.name, _data.path, _data.type, _data.loadType, _data.version, _data.MD5);
        }

        public void AddTask(string _name, string _path, EResType _type, ELoadTaskType _loadType, int _version, string MD5)
        {
            if (m_isLoading)
            {
                Debug.LogError("can`t add task then LoadManager is loading");
                return;
            }

            RepeatabilityDetection(_name);

            LoadTask task = new LoadTask(_name, _path, _type, _loadType, _version, MD5);

            if (task.loadType != ELoadTaskType.WEB)
            {
                return;
            }
            else
            {
                m_webTasks.Add(task);
            }
        }

        private void RepeatabilityDetection(string _name)
        {
            List<LoadTask>.Enumerator e = m_webTasks.GetEnumerator();

            while(e.MoveNext())
            {
                if (e.Current.name == _name)
                {
                    Debug.LogWarning("Already an same name task in Web Tasks");
                    return;
                }
            }
        }

        public void StartLoadTasks(OnLoadFinish _onLoadFinish)
        {
            m_isLoading = true;
            m_curIndex = 0;

           Mainloop.Instance.StartCoroutine(loadTasks(_onLoadFinish));
        }

        private IEnumerator loadTasks(OnLoadFinish _onLoadFinish)
        {
            bool success = true;
            int failNum = 0;
            
            for(int i = 0; i < m_webTasks.Count; i++) 
            {
                m_curTask = m_webTasks[i];
                m_curTask.Start();

                while (m_curTask.loadState != ELoadTaskState.SUCCESS && m_curTask.loadState != ELoadTaskState.FAILED)
                {
                    yield return null;
                }

                m_curTask.Unload();
                if (m_curTask.loadState != ELoadTaskState.SUCCESS)
                {
                    failNum++;
                    if (failNum < 3)
                    {
                        i--;
                        continue;
                    }
                    else
                    {
                        success = false;
                        break;
                    }
                }
                else
                {
                    ++m_curIndex;
                }

            }

            m_curTask = null;
            m_webTasks.Clear();
            yield return null;
            m_isLoading = false;
            if (_onLoadFinish != null)
            {
                _onLoadFinish(success);
            }
        }
    }

}
